package emulator.hardware.nmos6502.commands;

import emulator.EmulatorException;
import emulator.hardware.HwByte;
import emulator.hardware.nmos6502.Command;
import emulator.hardware.nmos6502.CommandSet;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.hardware.nmos6502.Flags6502;
import emulator.hardware.nmos6502.Operand;
import emulator.hardware.nmos6502.operands.*;

/**	ASO    ***    (SLO)
 *	This opcode ASLs the contents of a memory location and then ORs the result 
 *	with the accumulator.  
 *	
 *	Supported modes:
 *	
 *	ASO abcd        ;0F cd ab    ;No. Cycles= 6
 *	ASO abcd,X      ;1F cd ab    ;            7
 *	ASO abcd,Y      ;1B cd ab    ;            7
 *	ASO ab          ;07 ab       ;            5
 *	ASO ab,X        ;17 ab       ;            6
 *	ASO (ab,X)      ;03 ab       ;            8
 *	ASO (ab),Y      ;13 ab       ;            8
 *	
 *	(Sub-instructions: ORA, ASL)
 *	
 *	Here is an example of how you might use this opcode:
 *	
 *	ASO $C010       ;0F 10 C0
 *	
 *	Here is the same code using equivalent instructions.
 *	
 *	ASL $C010
 *	ORA $C010
 */

public class ASO implements Command {

	@Override
	public void execute(Cpu6502 cpu, Operand operand) throws EmulatorException {
		int value = (int) operand.getByte().getNumber();
		Flags6502 flags = cpu.getFlags();
		value = (value << 1) | value;
		flags.setCarry(value > 255);
		value &= 0xff;
		flags.setNZFromValue(value);
		operand.setByte(new HwByte(value));
		cpu.setFlags(flags);
	}

	@Override
	public String getName() {
		return "ASO";
	}

	@Override
	public void register(CommandSet cset) {
		cset.defineCommand(0x0F, this, new Absolute());
		cset.defineCommand(0x1F, this, new AbsoluteX());
		cset.defineCommand(0x1B, this, new AbsoluteY());
		cset.defineCommand(0x07, this, new ZeroPage());
		cset.defineCommand(0x17, this, new ZeroPageX());
		cset.defineCommand(0x03, this, new IndirectX());
		cset.defineCommand(0x13, this, new IndirectY());
	}

}
